// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.Serialization;
using InterpriseSuiteEcommerceCommon.Extensions;

namespace InterpriseSuiteEcommerceCommon.DTO
{
    [DataContractAttribute]
    public class ProductImage
    {
        public ProductImage() { }
        public ProductImage(string src, string relativeUrl)
        {
            this.src = src;
            this.rel = relativeUrl;
        }

        [DataMemberAttribute]
        public bool exists = false;

        [DataMemberAttribute]
        public string rel = string.Empty;

        [DataMemberAttribute]
        public string src = string.Empty;

        [DataMemberAttribute]
        public bool resizable = false;
        
        [DataMemberAttribute]
        public ImageSize size = new ImageSize();

        /// <summary>
        /// Will be used to call default image of item
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="ItemCode"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public static ProductImage LocateDefaultImage(string entity, string ItemCode, string size, string languageCode)
        {
            string ImgFilename = string.Empty;
            bool exists = false;
            bool existing = false;
            string defaultCondition = string.Empty;
            //there is no implementation yet for large image, skip for now
            if (!size.ToUpper().Equals("LARGE") && !size.ToUpper().Equals("MINICART"))
            {
                defaultCondition = string.Format("AND IsDefault{0} = 1", size);
            }

            if (size.ToUpper().Equals("MINICART"))
            {
                defaultCondition = string.Format("AND IsDefault{0} = 1", ImageSizeTypes.medium.ToString());
            }

            var productImage = new ProductImage();
            if (string.IsNullOrEmpty(languageCode))
            {
                ImgFilename = GetImageFileNameFromInventory(defaultCondition, ItemCode, size);
                existing = !ImgFilename.IsNullOrEmptyTrimmed();
            }
            else
            {
                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    string columnTitle = string.Empty;
                    string columnAlt = string.Empty;

                    switch (size.ToUpperInvariant())
                    {
                        case "ICON":
                            columnTitle = "SETitleIcon";
                            columnAlt = "SEAltTextIcon";
                            break;
                        case "MEDIUM":
                            columnTitle = "SETitleMedium";
                            columnAlt = "SEAltTextMedium";
                            break;
                        case "LARGE":
                            columnTitle = "SETitleLarge";
                            columnAlt = "SETitleLarge";
                            break;
                    }

                    string query = string.Format("SELECT a1.[FileName], b1.{4} TitleText, b1.{5} AltText FROM InventoryOverrideImage a1 with (NOLOCK) LEFT JOIN InventoryImageWebOptionDescription b1 with (NOLOCK) ON a1.ItemCode = b1.ItemCode WHERE a1.ItemCode = {0} {1} AND a1.WebsiteCode = {2} AND b1.LanguageCode = {3}",
                                                                 DB.SQuote(ItemCode), 
                                                                 defaultCondition, 
                                                                 DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode), 
                                                                 DB.SQuote(languageCode), 
                                                                 columnTitle, 
                                                                 columnAlt);
                    using (var reader = DB.GetRS(query, con))
                    {
                        existing = reader.Read();
                        if (existing)
                        {
                            ImgFilename = DB.RSField(reader, "Filename");
                            productImage.Title = DB.RSField(reader, "TitleText").Replace("'", "''").Trim().ToJavaScriptEscape();
                            productImage.Alt = DB.RSField(reader, "AltText").Replace("'", "''").Trim().ToJavaScriptEscape();
                        }
                    }
                }
            }
            string url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, size, ImgFilename, AppLogic.AppConfigBool("Watermark.Enabled"), out exists);           
            string relativeUrl = url;

            if (size == "large" && AppLogic.AppConfigBool("Watermark.Enabled"))
            {
                relativeUrl = AppLogic.LocateImageFilenameUrl(entity, ItemCode, size, ImgFilename, false, out exists);           
            }

            productImage.rel = relativeUrl;
            productImage.src = url;
            productImage.exists = exists;
            
            return productImage;
        }

        public static string GetImageFileNameFromInventory(string defaultCondition, string ItemCode, string size)
        {
            string imageFileName = string.Empty;
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "SELECT Filename FROM InventoryOverrideImage with (NOLOCK) WHERE ItemCode = {0} {1} AND WebSiteCode = {2}",
                                                            DB.SQuote(ItemCode),
                                                            defaultCondition,
                                                            DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode)))
                {
                    if (reader.Read())
                    {
                        imageFileName = DB.RSField(reader, "Filename");
                    }
                }
            }
            return imageFileName;
        }

        public static IEnumerable<ProductImage> LocateDefaultImageInSizes(string entity, string ItemCode)
        {
            bool exists = false;
            bool existing = false;
            string defaultCondition = string.Empty;
            List<ProductImage> lstImages = null;

            //get default image filename
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                string websiteCodeQuoted = DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode);
                string itemCodeQuoted = DB.SQuote(ItemCode);
                bool watermarkEnabled = AppLogic.AppConfigBool("Watermark.Enabled");

                string query = "{0};{1};{2}".FormatWith(
                                    "SELECT Filename FROM InventoryOverrideImage with (NOLOCK) WHERE ItemCode = {0} AND IsDefaulticon= 1 AND WebSiteCode = {1}".FormatWith(itemCodeQuoted, websiteCodeQuoted),
                                    "SELECT Filename FROM InventoryOverrideImage with (NOLOCK) WHERE ItemCode = {0} AND IsDefaultmedium = 1 AND WebSiteCode = {1}".FormatWith(itemCodeQuoted, websiteCodeQuoted),
                                    "SELECT Filename FROM InventoryOverrideImage with (NOLOCK) WHERE ItemCode = {0} AND IsDefaultmedium = 1 AND WebSiteCode = {1}".FormatWith(itemCodeQuoted, websiteCodeQuoted)
                                );

                using (var reader = DB.GetRS(query, con))
                {
                    lstImages = new List<ProductImage>();
                    string ImgFilename = string.Empty;
                    string url = string.Empty;
                    ImageSizeTypes type = ImageSizeTypes.icon;

                    //process Icon
                    existing = reader.Read();
                    if (existing) { ImgFilename = (DB.RSField(reader, "Filename")); }
                    url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, watermarkEnabled, out exists);
                    lstImages.Add(new ProductImage(url, url) { exists = exists, ImageSizeType = type, ImgFileName = ImgFilename });

                    //process Medium
                    if (reader.NextResult())
                    { 
                        existing = reader.Read();
                        type = ImageSizeTypes.medium;
                        if (existing) { ImgFilename = (DB.RSField(reader, "Filename")); }
                        url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, watermarkEnabled, out exists);
                        lstImages.Add(new ProductImage(url, url) { exists = exists, ImageSizeType = type, ImgFileName = ImgFilename });
                    }

                    //process large
                    if (reader.NextResult())
                    {
                        existing = reader.Read();
                        type = ImageSizeTypes.large;
                        if (existing) { ImgFilename = (DB.RSField(reader, "Filename")); }
                        url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, watermarkEnabled, out exists);
                        string relativeUrl = url;
                        if (watermarkEnabled) { relativeUrl = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, false, out exists); }
                        lstImages.Add(new ProductImage(url, relativeUrl) { exists = exists, ImageSizeType = type, ImgFileName = ImgFilename });
                    }

                }
            }

            return lstImages;
        }

        public static IEnumerable<ProductImage> LocateDefaultImageInSizesForFileUpload(string entity, string ItemCode)
        {
            bool exists = false;
            bool existing = false;
            string defaultCondition = string.Empty;
            List<ProductImage> lstImages = null;

            //get default image filename
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                string websiteCodeQuoted = DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode);
                string itemCodeQuoted = DB.SQuote(ItemCode);
                bool watermarkEnabled = AppLogic.AppConfigBool("Watermark.Enabled");

                string query = "{0};{1};{2}".FormatWith(
                                    "SELECT Filename FROM InventoryOverrideImage with (NOLOCK) WHERE IsDefaultIcon = 1 AND ItemCode = {0} AND WebSiteCode = {1}"
                                        .FormatWith(itemCodeQuoted, websiteCodeQuoted),
                                    "SELECT Filename, IsDefaultIcon, IsDefaultMedium FROM InventoryOverrideImage with (NOLOCK) WHERE IsDefaultMedium = 1 AND ItemCode = {0} AND WebSiteCode = {1}"
                                        .FormatWith(itemCodeQuoted, websiteCodeQuoted),
                                    "SELECT Filename, IsDefaultIcon, IsDefaultMedium FROM InventoryOverrideImage with (NOLOCK) WHERE IsDefaultMedium = 1 AND ItemCode = {0} AND WebSiteCode = {1}"
                                        .FormatWith(itemCodeQuoted, websiteCodeQuoted)
                                );

                using (var reader = DB.GetRS(query, con))
                {
                    lstImages = new List<ProductImage>();
                    string ImgFilename = string.Empty;
                    string url = string.Empty;
                    ImageSizeTypes type = ImageSizeTypes.icon;

                    //process Icon
                    existing = reader.Read();
                    if (existing) { ImgFilename = (DB.RSField(reader, "Filename")); }
                    url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, watermarkEnabled, out exists);
                    lstImages.Add(new ProductImage(url, url) { exists = exists, ImageSizeType = type, ImgFileName = ImgFilename, IsDefaultIcon = true });

                    //process Medium
                    if (reader.NextResult())
                    {
                        existing = reader.Read();
                        type = ImageSizeTypes.medium;
                        if (existing) { ImgFilename = (DB.RSField(reader, "Filename")); }
                        url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, watermarkEnabled, out exists);
                        lstImages.Add(new ProductImage(url, url) { exists = exists, ImageSizeType = type, ImgFileName = ImgFilename, IsDefaultMedium = true });
                    }

                    //process large
                    if (reader.NextResult())
                    {
                        existing = reader.Read();
                        type = ImageSizeTypes.large;
                        if (existing) { ImgFilename = (DB.RSField(reader, "Filename")); }
                        url = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, watermarkEnabled, out exists);
                        string relativeUrl = url;
                        if (watermarkEnabled) { relativeUrl = AppLogic.LocateImageFilenameUrl(entity, ItemCode, type.ToString(), ImgFilename, false, out exists); }
                        lstImages.Add(new ProductImage(url, relativeUrl) { exists = exists, ImageSizeType = type, ImgFileName = ImgFilename, IsDefaultMedium = true });
                    }

                }
            }

            return lstImages;
        }

        public static IEnumerable<ProductImage> LocateBulkDefaultImages(string entity, string size, string languageCode, bool locateWithAttributes, IEnumerable<string> lstItemCodes = null, IEnumerable<string> lstEntityID = null)
        {
            List<ProductImage> lstProductImages = null;
            IEnumerable<string> tempIndentities = (lstItemCodes != null) ? lstItemCodes : lstEntityID;
            bool isProduct = (lstItemCodes != null);

            string ImgFilename = string.Empty;
            bool exists = false;
            string defaultCondition = string.Empty;

            //there is no implementation yet for large image, skip for now
            if (!size.ToUpper().Equals("LARGE"))
            {
                defaultCondition = string.Format("AND IsDefault{0} = 1", size);
            }

            string idsOrCodes = string.Join(",", tempIndentities.Select(item => DB.SQuote(item)));

            if (languageCode.IsNullOrEmptyTrimmed())
            {
                lstProductImages = GetImagesFromInventory(defaultCondition, tempIndentities, size).ToList();
            }
            else
            {
                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    string columnTitle = string.Empty;
                    string columnAlt = string.Empty;

                    switch (size.ToUpperInvariant())
                    {
                        case "ICON":
                            columnTitle = "SETitleIcon";
                            columnAlt = "SEAltTextIcon";
                            break;
                        case "MEDIUM":
                            columnTitle = "SETitleMedium";
                            columnAlt = "SEAltTextMedium";
                            break;
                        case "LARGE":
                            columnTitle = "SETitleLarge";
                            columnAlt = "SETitleLarge";
                            break;
                    }

                    string query = string.Format("SELECT a1.[ItemCode], a1.[Counter], a1.[FileName], b1.{4} TitleText, b1.{5} AltText FROM InventoryOverrideImage a1 with (NOLOCK) LEFT JOIN InventoryImageWebOptionDescription b1 with (NOLOCK) ON a1.ItemCode = b1.ItemCode WHERE a1.ItemCode IN ({0}) AND (a1.WebsiteCode = {2} AND b1.LanguageCode = {3} {1})",
                                                                 idsOrCodes,
                                                                 defaultCondition,
                                                                 DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode),
                                                                 DB.SQuote(languageCode),
                                                                 columnTitle,
                                                                 columnAlt);
                    using (var reader = DB.GetRS(query, con))
                    {
                        lstProductImages = new List<ProductImage>();
                        while (reader.Read())
                        {
                            string itemCode = DB.RSField(reader, "ItemCode").Replace("'", "''");
                            int counter = DB.RSFieldInt(reader, "Counter");

                            if (lstProductImages.Any(p => p.Code == itemCode || p.Counter == counter)) continue;

                            var productImage = new ProductImage();
                            productImage.Title = DB.RSField(reader, "TitleText").Replace("'", "''").Trim().ToJavaScriptEscape();
                            productImage.Alt = DB.RSField(reader, "AltText").Replace("'", "''").Trim().ToJavaScriptEscape();
                            productImage.Code = itemCode;
                            productImage.Counter = counter;
                            productImage.ImgFileName = DB.RSField(reader, "Filename");

                            lstProductImages.Add(productImage);
                        }
                    }
                }
            }

            //no records found or some found.
            if (lstProductImages.Count() != tempIndentities.Count())
            {
                var lstNoImage = tempIndentities.Except(lstProductImages.Select(img => img.Code));
                lstNoImage.ForEach(item => lstProductImages.Add(new ProductImage() { Code = item, ImgFileName = string.Empty }));
            }

            tempIndentities.ForEach(code =>
            {
                var selImage = lstProductImages.FirstOrDefault(item => item.Code == code);

                string imgFileName = selImage.ImgFileName;
                string url = AppLogic.LocateImageFilenameUrl(entity, code, size, imgFileName, AppLogic.AppConfigBool("Watermark.Enabled"), out exists);
                string relativeUrl = url;

                if (size == "large" && AppLogic.AppConfigBool("Watermark.Enabled"))
                {
                    relativeUrl = AppLogic.LocateImageFilenameUrl(entity, code, size, ImgFilename, false, out exists);
                }

                selImage.rel = relativeUrl;
                selImage.src = url;
                selImage.exists = exists;

            });

            return lstProductImages;
        }

        private static IEnumerable<ProductImage> GetImagesFromInventory(string defaultCondition, IEnumerable<string> itemCodes, string size)
        {
            string codes = string.Join(",", itemCodes.Select(item => DB.SQuote(item)));
            string imageFileName = string.Empty;

            var lstProductImages = new List<ProductImage>();
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "SELECT Filename, ItemCode, Counter FROM InventoryOverrideImage with (NOLOCK) WHERE ItemCode IN ({0}) AND (WebSiteCode = {2} {1})",
                                                            codes,
                                                            defaultCondition,
                                                            DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode)))
                {
                    while (reader.Read())
                    {
                        var productImage = new ProductImage()
                        {
                            Code = DB.RSField(reader, "ItemCode"),
                            Counter = DB.RSFieldInt(reader, "Counter"),
                            ImgFileName = DB.RSField(reader, "Filename")
                        };
                        lstProductImages.Add(productImage);
                    }
                }
            }
            return lstProductImages;
        }

        public static ProductImage Locate(string entity, int id, string size)
        {
            return LocateDefaultImage(entity, InterpriseHelper.GetInventoryItemCode(id), size, string.Empty);
        }

        public static ProductImage Locate(string entity, string itemCode, string size)
        {
            return LocateDefaultImage(entity, itemCode, size, string.Empty);
        }

        /// <summary>
        /// Include the image attributes
        /// </summary>
        public static ProductImage Locate(string entity, string itemCode, string size, string languageCode)
        {
            return LocateDefaultImage(entity, itemCode, size, languageCode);
        }

        public static ProductImage Locate(string entity, int id, string size, int index)
        {
            bool exists = false;

            string url = AppLogic.LocateImageUrl(entity, id, size, index, AppLogic.AppConfigBool("Watermark.Enabled"), out exists);
            
            string relativeUrl = url;

            if (size == "large" && AppLogic.AppConfigBool("Watermark.Enabled"))
            {
                relativeUrl = AppLogic.LocateImageUrl(entity, id, size, index, false, out exists);
            }

            ProductImage img = new ProductImage(url, relativeUrl);
            img.exists = exists;

            return img;
        }

        public static ProductImage LocateMultiImage(string entity, string itemcode, string filename, string size)
        {
            bool exists = false;

            string url = AppLogic.LocateImageFilenameUrl(entity, itemcode, size, filename, AppLogic.AppConfigBool("Watermark.Enabled"), out exists);

            string relativeUrl = url;

            if (size == "large" && AppLogic.AppConfigBool("Watermark.Enabled"))
            {
                relativeUrl = AppLogic.LocateImageFilenameUrl(entity, itemcode, size, filename, false, out exists);
            }

            return new ProductImage(url, relativeUrl)
            {
                exists = exists,
                ImgFileName = filename
            };
        }

        [DataMemberAttribute]
        public ImageSizeTypes ImageSizeType { get; set; }

        [DataMemberAttribute]
        public string Title { get; set; }

        [DataMemberAttribute]
        public string Alt { get; set; }

        //For Bulk caching
        public string Code { get; set; }

        //For Bulk caching
        public int Counter { get; set; }

        //For Bulk caching
        [DataMemberAttribute]
        public string ImgFileName { get; set; }

        //For Bulk caching
        [DataMemberAttribute]
        public bool IsDefaultMedium { get; set; }

        //For Bulk caching
        [DataMemberAttribute]
        public bool IsDefaultIcon { get; set; }

    }

    public class ImageSize
    {
        public int width = 0;
        public int height = 0;
    }

    public enum ImageSizeTypes
    { 
        icon,
        medium,
        large,
        minicart,
        mobile
    }

}
